Cerebellar statistical overlay¶

This demo shows the SUIT atlas. This jupyter notebook mimics the SUIT atlas web page.

In [1]:
from pathlib import Path

from ipyniivue import download_dataset

BASE_API_URL = "https://niivue.com/demos/images/"
DATA_FOLDER = Path("images")

download_dataset(
    BASE_API_URL,
    DATA_FOLDER,
    files=[
        "FLAT.surf.gii",
        "SUIT.shape.gii",
        "Lobules.label.gii",
    ],
)
FLAT.surf.gii already exists.
SUIT.shape.gii already exists.
Lobules.label.gii already exists.
Dataset downloaded successfully to images.
In [2]:
import ipywidgets as widgets

from ipyniivue import NiiVue

## Initialize Viewer and Layer Indices

nv = NiiVue(
    back_color=(1, 1, 1, 1),
    show_3d_crosshair=True,
    is_colorbar=True,
)

kCurvLayer = 0
kAltasLayer = 1
kStatLayer = 2

## Load Mesh and Layers

mesh_layers = [
    {
        "path": DATA_FOLDER / "SUIT.shape.gii",
        "opacity": 1,
        "colormap": "gray",
        "cal_min": -1.5,
        "cal_max": 1,
    },
    {"path": DATA_FOLDER / "Lobules.label.gii", "opacity": 0.05},
    {"path": DATA_FOLDER / "Lobules.label.gii", "opacity": 0.65},
]

nv.load_meshes(
    [
        {"path": DATA_FOLDER / "FLAT.surf.gii", "layers": mesh_layers},
    ]
)

nv.opts.show_legend = False
nv.meshes[0].layers[0].colorbar_visible = False
nv.set_render_azimuth_elevation(0, 90)
nv.set_mesh_shader(nv.meshes[0].id, "Rim")

## Configure Statistical Layer


@nv.on_mesh_loaded
def on_mesh_loaded(mesh):
    """Handle event after mesh is loaded and ready."""
    nv.meshes[0].layers[kStatLayer].cal_min = 2.3
    nv.meshes[0].layers[kStatLayer].cal_max = 5
    nv.meshes[0].layers[kStatLayer].colormap = "warm"
    nv.meshes[0].layers[kStatLayer].colormap_negative = "winter"
    nv.meshes[0].layers[kStatLayer].use_negative_cmap = True
    nv.meshes[0].layers[kCurvLayer].colorbar_visible = False
    nv.meshes[0].layers[kAltasLayer].colorbar_visible = False

    vals = [
        0,
        2,
        0,
        0,
        0,
        3,
        0,
        0,
        0,
        0,
        0,
        6,
        0,
        -4,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
    ]
    nv.set_mesh_layer_property(nv.meshes[0].id, kStatLayer, "atlas_values", vals)


## Create Interactive Controls

curv_slider = widgets.IntSlider(
    value=100, min=1, max=100, description="Curvature", readout=False
)


def on_curv_change(change):
    """Set curve transparency."""
    nv.set_mesh_layer_property(
        mesh_id=nv.meshes[0].id,
        layer_index=kCurvLayer,
        attribute="opacity",
        value=change["new"] * 0.01,
    )


curv_slider.observe(on_curv_change, names="value")

atlas_slider = widgets.IntSlider(
    value=5, min=0, max=100, description="Atlas", readout=False
)


def on_atlas_change(change):
    """Set atlas transparency."""
    nv.set_mesh_layer_property(
        mesh_id=nv.meshes[0].id,
        layer_index=kAltasLayer,
        attribute="opacity",
        value=change["new"] * 0.01,
    )


atlas_slider.observe(on_atlas_change, names="value")

stat_slider = widgets.IntSlider(
    value=65, min=0, max=100, description="Stats", readout=False
)


def on_stat_change(change):
    """Set stat transparency."""
    nv.set_mesh_layer_property(
        mesh_id=nv.meshes[0].id,
        layer_index=kStatLayer,
        attribute="opacity",
        value=change["new"] * 0.01,
    )


stat_slider.observe(on_stat_change, names="value")

border_options = ["Dark border", "Transparent border", "No border", "Opaque border"]
border_dropdown = widgets.Dropdown(
    options=border_options,
    value="Opaque border",
    description="Border",
)


def on_border_change(change):
    """Set mesh border style."""
    value_name = change["new"]
    borderValue = 0.0  # Default for "No border"

    if value_name == "Dark border":
        borderValue = -0.01
    elif value_name == "Transparent border":
        borderValue = 0.01
    elif value_name == "Opaque border":
        borderValue = 1.0

    nv.set_mesh_layer_property(
        nv.meshes[0].id, kAltasLayer, "outline_border", borderValue
    )

    labels = nv.meshes[0].layers[kStatLayer].atlas_labels
    nlabels = len(labels)
    print(f"labels [{nlabels}]: {labels}")


border_dropdown.observe(on_border_change, names="value")

## Display Viewer

widgets.VBox(
    [
        widgets.HBox([curv_slider, atlas_slider, stat_slider, border_dropdown]),
        nv,
    ]
)
Out[2]: